<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="laravel-的-api-认证系统-passport" tabindex="-1"><a class="header-anchor" href="#laravel-的-api-认证系统-passport"><span>Laravel 的 API 认证系统 Passport</span></a></h2>
<ul>
<li><a href="#introduction">介绍</a></li>
<li><a href="#installation">安装</a>
<ul>
<li><a href="#frontend-quickstart">前端快速上手</a></li>
<li><a href="#deploying-passport">部署 Passport</a></li>
</ul>
</li>
<li><a href="#configuration">配置</a>
<ul>
<li><a href="#token-lifetimes">令牌的使用期限</a></li>
</ul>
</li>
<li><a href="#issuing-access-tokens">发放访问令牌</a>
<ul>
<li><a href="#managing-clients">管理客户端</a></li>
<li><a href="#requesting-tokens">请求令牌</a></li>
<li><a href="#refreshing-tokens">刷新令牌</a></li>
</ul>
</li>
<li><a href="#password-grant-tokens">密码授权令牌</a>
<ul>
<li><a href="#creating-a-password-grant-client">创建密码授权客户端</a></li>
<li><a href="#requesting-password-grant-tokens">请求密码授权令牌</a></li>
<li><a href="#requesting-all-scopes">请求所有作用域</a></li>
</ul>
</li>
<li><a href="#implicit-grant-tokens">简化授权令牌</a></li>
<li><a href="#client-credentials-grant-tokens">客户端授权令牌</a></li>
<li><a href="#personal-access-tokens">个人访问令牌</a>
<ul>
<li><a href="#creating-a-personal-access-client">创建个人访问令牌的客户端</a></li>
<li><a href="#managing-personal-access-tokens">管理个人访问令牌</a></li>
</ul>
</li>
<li><a href="#protecting-routes">路由保护</a>
<ul>
<li><a href="#via-middleware">通过中间件</a></li>
<li><a href="#passing-the-access-token">传递访问令牌</a></li>
</ul>
</li>
<li><a href="#token-scopes">令牌作用域</a>
<ul>
<li><a href="#defining-scopes">定义作用域</a></li>
<li><a href="#assigning-scopes-to-tokens">给令牌分配作用域</a></li>
<li><a href="#checking-scopes">检查作用域</a></li>
</ul>
</li>
<li><a href="#consuming-your-api-with-javascript">使用 JavaScript 接入 API</a></li>
<li><a href="#events">事件</a></li>
<li><a href="#testing">测试</a></li>
</ul>
<h2 id="介绍" tabindex="-1"><a class="header-anchor" href="#介绍"><span>介绍</span></a></h2>
<p>在 Laravel 中，实现基于传统表单的登陆和授权已经非常简单，但是如何满足 API 场景下的授权需求呢？在 API 场景里通常通过令牌来实现用户授权，而非维护请求之间的 Session 状态。在 Laravel 项目中使用 Passport 可以轻而易举地实现 API 授权认证，Passport 可以在几分钟之内为你的应用程序提供完整的 OAuth2 服务端实现。Passport 是基于由 <a href="https://github.com/alexbilbie" target="_blank" rel="noopener noreferrer">Alex Bilbie</a> 维护的 <a href="https://github.com/thephpleague/oauth2-server" target="_blank" rel="noopener noreferrer">League OAuth2 server</a> 建立的。</p>
<blockquote>
<p>{note} 本文档假定你已熟悉 OAuth2 。如果你并不了解 OAuth2 ，阅读之前请先熟悉下 OAuth2 的常用术语和功能。</p>
</blockquote>
<h2 id="安装" tabindex="-1"><a class="header-anchor" href="#安装"><span>安装</span></a></h2>
<p>使用 Composer 安装 Passport ：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">composer <span class="token keyword">require</span> laravel<span class="token operator">/</span>passport<span class="token operator">=</span><span class="token operator">~</span><span class="token number">4.0</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>Passport 服务提供器使用框架注册自己的数据库迁移目录，因此在注册提供器后，就应该运行 Passport 的迁移命令来自动创建存储客户端和令牌的数据表：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan migrate</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>{note} 如果你不打算使用 Passport 的默认迁移，你应该在 <code v-pre>AppServiceProvider</code> 的 <code v-pre>register</code> 方法中调用 <code v-pre>Passport::ignoreMigrations</code> 方法。 你可以用这个命令 <code v-pre>php artisan vendor:publish --tag=passport-migrations</code> 导出默认迁移。</p>
</blockquote>
<p>接下来，运行 <code v-pre>passport:install</code> 命令来创建生成安全访问令牌时所需的加密密钥，同时，这条命令也会创建用于生成访问令牌的「个人访问」客户端和「密码授权」客户端：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan passport<span class="token punctuation">:</span>install</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>上面命令执行后，请将 <code v-pre>Laravel\Passport\HasApiTokens</code> Trait 添加到 <code v-pre>App\User</code> 模型中，这个 Trait 会给你的模型提供一些辅助函数，用于检查已认证用户的令牌和使用范围：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Passport<span class="token punctuation">\</span>HasApiTokens</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Notifications<span class="token punctuation">\</span>Notifiable</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Auth<span class="token punctuation">\</span>User</span> <span class="token keyword">as</span> Authenticatable<span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">User</span> <span class="token keyword">extends</span> <span class="token class-name">Authenticatable</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">use</span> <span class="token package">HasApiTokens</span><span class="token punctuation">,</span> Notifiable<span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>接下来，在 <code v-pre>AuthServiceProvider</code> 的 <code v-pre>boot</code> 方法中调用 <code v-pre>Passport::routes</code> 函数。这个函数会注册发出访问令牌并撤销访问令牌、客户端和个人访问令牌所必需的路由：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Passport<span class="token punctuation">\</span>Passport</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Gate</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Foundation<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Providers<span class="token punctuation">\</span>AuthServiceProvider</span> <span class="token keyword">as</span> ServiceProvider<span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">AuthServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 应用程序的策略映射。</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">array</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">protected</span> <span class="token variable">$policies</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'App\Model'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'App\Policies\ModelPolicy'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * Register any authentication / authorization services.</span>
<span class="line">     *</span>
<span class="line">     * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">registerPolicies</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">routes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>最后，将配置文件 <code v-pre>config/auth.php</code> 中授权看守器 <code v-pre>guards</code> 的 <code v-pre>api</code> 的 <code v-pre>driver</code> 选项改为 <code v-pre>passport</code>。此调整会让你的应用程序在在验证传入的 API 的请求时使用 Passport 的 <code v-pre>TokenGuard</code> 来处理：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'guards'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'web'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'session'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'provider'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'users'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token string single-quoted-string">'api'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'driver'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'passport'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'provider'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'users'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="前端快速上手" tabindex="-1"><a class="header-anchor" href="#前端快速上手"><span>前端快速上手</span></a></h3>
<blockquote>
<p>{note} 如果想要使用 Passport 的 Vue 组件，那么你必须使用 <a href="https://vuejs.org/" target="_blank" rel="noopener noreferrer">Vue</a> Javascript 框架，另外这些组件还用到了 Bootstrap CSS 框架。当然你也可以不使用上面的任何工具，但在实现你自己的前端部分时，Passport 的 Vue 组件仍旧有很高的参考价值。</p>
</blockquote>
<p>Passport 配备了一些可以让你的用户自行创建客户端和个人访问令牌的 JSON API。然而，编写一些前端代码来与这些 API 进行交互很是耗时。因此 Passport 也引入了预先构建的 <a href="https://vuejs.org/" target="_blank" rel="noopener noreferrer">Vue</a> 组件，你可以直接使用，也可以基于这些代码实现自己的前端部分。</p>
<p>使用 Artisan 命令 <code v-pre>vendor:publish</code> 来发布 Passport 的 Vue 组件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan vendor<span class="token punctuation">:</span>publish <span class="token operator">--</span>tag<span class="token operator">=</span>passport<span class="token operator">-</span>components</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>已发布的组件将被放置在 <code v-pre>resources/assets/js/components</code> 目录中，可以在 <code v-pre>resources/assets/js/app.js</code> 文件中注册它们：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">Vue<span class="token operator">.</span><span class="token function">component</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token string single-quoted-string">'passport-clients'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token keyword">require</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'./components/passport/Clients.vue'</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">Vue<span class="token operator">.</span><span class="token function">component</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token string single-quoted-string">'passport-authorized-clients'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token keyword">require</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'./components/passport/AuthorizedClients.vue'</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">Vue<span class="token operator">.</span><span class="token function">component</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token string single-quoted-string">'passport-personal-access-tokens'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token keyword">require</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'./components/passport/PersonalAccessTokens.vue'</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这些组件注册后，运行 <code v-pre>npm install</code>安装vue所依赖的文件，运行<code v-pre>npm run dev</code> 命令以确保重新编译你的资源。重新编译资源后，你可以将这些组件放入应用程序的模板中，然后开始创建客户端和个人访问令牌：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token operator">&lt;</span>passport<span class="token operator">-</span>clients<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>passport<span class="token operator">-</span>clients<span class="token operator">></span></span>
<span class="line"><span class="token operator">&lt;</span>passport<span class="token operator">-</span>authorized<span class="token operator">-</span>clients<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>passport<span class="token operator">-</span>authorized<span class="token operator">-</span>clients<span class="token operator">></span></span>
<span class="line"><span class="token operator">&lt;</span>passport<span class="token operator">-</span>personal<span class="token operator">-</span>access<span class="token operator">-</span>tokens<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">/</span>passport<span class="token operator">-</span>personal<span class="token operator">-</span>access<span class="token operator">-</span>tokens<span class="token operator">></span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="部署-passport" tabindex="-1"><a class="header-anchor" href="#部署-passport"><span>部署 Passport</span></a></h3>
<p>第一次将 Passport 部署到生产服务器时，需要运行 <code v-pre>passport:keys</code> 命令。该命令生成 Passport 所需要的用来产生访问令牌的加密密钥。生成的这些密钥不会保存在源码控制中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan passport<span class="token punctuation">:</span>keys</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="配置" tabindex="-1"><a class="header-anchor" href="#配置"><span>配置</span></a></h2>
<h3 id="令牌的有效期" tabindex="-1"><a class="header-anchor" href="#令牌的有效期"><span>令牌的有效期</span></a></h3>
<p>默认情况下，Passport 发放的访问令牌是永久有效的，不需要刷新。但是如果你想自定义访问令牌的有效期，可以使用 <code v-pre>tokensExpireIn</code> 和 <code v-pre>refreshTokensExpireIn</code> 方法。上述两个方法同样需要在 <code v-pre>AuthServiceProvider</code> 的 <code v-pre>boot</code> 方法中调用：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Carbon<span class="token punctuation">\</span>Carbon</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * Register any authentication / authorization services.</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">registerPolicies</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">routes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">tokensExpireIn</span><span class="token punctuation">(</span><span class="token class-name static-context">Carbon</span><span class="token operator">::</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">addDays</span><span class="token punctuation">(</span><span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">refreshTokensExpireIn</span><span class="token punctuation">(</span><span class="token class-name static-context">Carbon</span><span class="token operator">::</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">addDays</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="发放访问令牌" tabindex="-1"><a class="header-anchor" href="#发放访问令牌"><span>发放访问令牌</span></a></h2>
<p>熟悉 OAuth2 的开发者一定知道， OAuth2 中必不可少的部分就是授权码。当使用授权码时，客户端应用程序会将用户重定向到你的服务器，他们将批准或拒绝向客户端发出访问令牌的请求。</p>
<h3 id="管理客户端" tabindex="-1"><a class="header-anchor" href="#管理客户端"><span>管理客户端</span></a></h3>
<p>首先，构建需要与应用程序 API 交互的应用程序，开发人员将需要通过创建一个「客户端」来注册自己的应用程序。一般来说，这包括在用户批准其授权请求后，提供其应用程序的名称和应用程序可以重定向到的 URL。</p>
<h4 id="passport-client-命令" tabindex="-1"><a class="header-anchor" href="#passport-client-命令"><span><code v-pre>passport:client</code> 命令</span></a></h4>
<p>创建客户端最简单的方式是使用 Artisan 命令 <code v-pre>passport:client</code>，你可以使用此命令创建自己的客户端，用于测试你的 OAuth2 的功能。在你执行 <code v-pre>client</code> 命令时，Passport 会提示你输入有关客户端的信息，最终会给你提供客户端的 ID 和 密钥：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan passport<span class="token punctuation">:</span>client</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="json-api" tabindex="-1"><a class="header-anchor" href="#json-api"><span>JSON API</span></a></h4>
<p>考虑到你的用户无法使用 <code v-pre>client</code> 命令，Passport 为此提供了可用于创建客户端的 JSON API。这样你就不用再花时间编写控制器来创建、更新和删除客户端。</p>
<p>然而，你仍旧需要基于 Passport 的 JSON API 开发一套前端界面，为你的用户提供管理客户端的仪表板。下面我们会列出所有用于管理客户端的 API，为了方便起见，我们使用 <a href="https://github.com/mzabriskie/axios" target="_blank" rel="noopener noreferrer">Axios</a> 来演示对端口发出 HTTP 请求。</p>
<blockquote>
<p>{tip} 如果你不想自己实现整个客户端管理的前端界面，可以使用 <a href="#frontend-quickstart">前端快速上手</a> 在几分钟内组建一套功能齐全的前端界面。</p>
</blockquote>
<h4 id="get-oauth-clients" tabindex="-1"><a class="header-anchor" href="#get-oauth-clients"><span><code v-pre>GET /oauth/clients</code></span></a></h4>
<p>此路由会返回认证用户的所有客户端。主要用途是列出所有用户的客户端，以便他们可以编辑或删除它们：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">axios<span class="token operator">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/clients'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        console<span class="token operator">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token operator">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="post-oauth-clients" tabindex="-1"><a class="header-anchor" href="#post-oauth-clients"><span><code v-pre>POST /oauth/clients</code></span></a></h4>
<p>此路由用于创建新客户端。它需要两部分数据：客户端的 <code v-pre>name</code> 和 <code v-pre>redirect</code> 的链接。在批准或拒绝授权请求后，用户会被重定向 <code v-pre>redirect</code> 到这个链接。</p>
<p>创建客户端时，会发出此客户端的 ID 和密钥。客户端可以使用这两个值从你的应用程序请求访问令牌。该路由会返回新的客户端实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token punctuation">{</span></span>
<span class="line">    name<span class="token punctuation">:</span> <span class="token string single-quoted-string">'Client Name'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token argument-name">redirect</span><span class="token punctuation">:</span> <span class="token string single-quoted-string">'http://example.com/callback'</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">axios<span class="token operator">.</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/clients'</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        console<span class="token operator">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token operator">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">response</span> <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// List errors on response...</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="put-oauth-clients-client-id" tabindex="-1"><a class="header-anchor" href="#put-oauth-clients-client-id"><span><code v-pre>PUT /oauth/clients/{client-id}</code></span></a></h4>
<p>此路由用于更新客户端信息。它需要两部分数据：客户端的 <code v-pre>name</code> 和 <code v-pre>redirect</code> 的链接。在批准或拒绝授权请求后，用户会被重定向 <code v-pre>redirect</code> 到这个链接。此路由会返回更新的客户端实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token punctuation">{</span></span>
<span class="line">    name<span class="token punctuation">:</span> <span class="token string single-quoted-string">'New Client Name'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token argument-name">redirect</span><span class="token punctuation">:</span> <span class="token string single-quoted-string">'http://example.com/callback'</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">axios<span class="token operator">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/clients/'</span> <span class="token operator">+</span> clientId<span class="token punctuation">,</span> data<span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        console<span class="token operator">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token operator">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">response</span> <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// List errors on response...</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="delete-oauth-clients-client-id" tabindex="-1"><a class="header-anchor" href="#delete-oauth-clients-client-id"><span><code v-pre>DELETE /oauth/clients/{client-id}</code></span></a></h4>
<p>此路由用于删除客户端：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">axios<span class="token operator">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/clients/'</span> <span class="token operator">+</span> clientId<span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">//</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="请求令牌" tabindex="-1"><a class="header-anchor" href="#请求令牌"><span>请求令牌</span></a></h3>
<h4 id="授权时的重定向" tabindex="-1"><a class="header-anchor" href="#授权时的重定向"><span>授权时的重定向</span></a></h4>
<p>客户端创建之后，开发者会使用此客户端的 ID 和密钥来请求授权代码，并从应用程序访问令牌。首先，接入应用的用户向你应用程序的 <code v-pre>/oauth/authorize</code> 路由发出重定向请求，示例如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/redirect'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$query</span> <span class="token operator">=</span> <span class="token function">http_build_query</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'redirect_uri'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'http://example.com/callback'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'response_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'code'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">return</span> <span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/authorize?'</span><span class="token operator">.</span><span class="token variable">$query</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>{tip} 注意，路由 <code v-pre>/oauth/authorize</code> 已经在 <code v-pre>Passport::routes</code> 方法中定义。你不需要手动定义此路由。</p>
</blockquote>
<h4 id="批准请求" tabindex="-1"><a class="header-anchor" href="#批准请求"><span>批准请求</span></a></h4>
<p>接收到授权请求时，Passport 会自动向用户显示一个模版页面，允许用户批准或拒绝授权请求。如果用户批准请求，他们会被重定向回接入的应用程序指定的 <code v-pre>redirect_uri</code>。<code v-pre>redirect_uri</code> 必须和客户端创建时指定的 <code v-pre>redirect</code> 链接完全一致。</p>
<p>如果你想自定义授权确认页面，可以使用 Artisan 命令 <code v-pre>vendor:publish</code> 发布 Passport 的视图。发布后的视图文件存放在 <code v-pre>resources/views/vendor/passport</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan vendor<span class="token punctuation">:</span>publish <span class="token operator">--</span>tag<span class="token operator">=</span>passport<span class="token operator">-</span>views</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="将授权码转换为访问令牌" tabindex="-1"><a class="header-anchor" href="#将授权码转换为访问令牌"><span>将授权码转换为访问令牌</span></a></h4>
<p>用户批准授权请求后，会被重定向回接入的应用程序。然后接入应用应该将通过 <code v-pre>POST</code> 请求向你的应用程序申请访问令牌。请求应该包括当用户批准授权请求时由应用程序发出的授权码。在下面的例子中，我们使用 Guzzle HTTP 库来实现这次 <code v-pre>POST</code> 请求：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/callback'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$http</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name class-name-fully-qualified">GuzzleHttp<span class="token punctuation">\</span>Client</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$http</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/token'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'form_params'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'grant_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'authorization_code'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'client_secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-secret'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'redirect_uri'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'http://example.com/callback'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'code'</span> <span class="token operator">=></span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token property">code</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">return</span> <span class="token function">json_decode</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword type-casting">string</span><span class="token punctuation">)</span> <span class="token variable">$response</span><span class="token operator">-></span><span class="token function">getBody</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>路由 <code v-pre>/oauth/token</code> 返回的 JSON 响应中会包含 <code v-pre>access_token</code> 、<code v-pre>refresh_token</code> 和 <code v-pre>expires_in</code> 属性。<code v-pre>expires_in</code> 属性包含访问令牌的有效期（单位：秒）。</p>
<blockquote>
<p>{tip} 像 <code v-pre>/oauth/authorize</code> 路由一样，<code v-pre>/oauth/token</code> 路由在 <code v-pre>Passport::routes</code> 方法中定义了。</p>
</blockquote>
<h3 id="刷新令牌" tabindex="-1"><a class="header-anchor" href="#刷新令牌"><span>刷新令牌</span></a></h3>
<p>如果你的应用程序发放了短期的访问令牌，用户将需要通过在发出访问令牌时提供给他们的刷新令牌来刷新其访问令牌。在下面的例子中，我们使用 Guzzle HTTP 库来刷新令牌：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$http</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name class-name-fully-qualified">GuzzleHttp<span class="token punctuation">\</span>Client</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$http</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/token'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'form_params'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'grant_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'refresh_token'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'refresh_token'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'the-refresh-token'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-secret'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">return</span> <span class="token function">json_decode</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword type-casting">string</span><span class="token punctuation">)</span> <span class="token variable">$response</span><span class="token operator">-></span><span class="token function">getBody</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>路由 <code v-pre>/oauth/token</code> 会返回一个 JSON 响应，其中包含 <code v-pre>access_token</code> 、<code v-pre>refresh_token</code> 和 <code v-pre>expires_in</code> 属性。<code v-pre>expires_in</code> 属性包含访问令牌的有效时间（单位：秒）。</p>
<h2 id="密码授权令牌" tabindex="-1"><a class="header-anchor" href="#密码授权令牌"><span>密码授权令牌</span></a></h2>
<p>OAuth2 密码授权机制可以让你自己的客户端（如移动应用程序）邮箱地址或者用户名和密码获取访问令牌。如此一来你就可以安全地向自己的客户端发出访问令牌，而不需要遍历整个 OAuth2 授权代码重定向流程。</p>
<h3 id="创建密码授权客户端" tabindex="-1"><a class="header-anchor" href="#创建密码授权客户端"><span>创建密码授权客户端</span></a></h3>
<p>在应用程序通过密码授权机制来发布令牌之前，在 <code v-pre>passport:client</code> 命令后加上 <code v-pre>--password</code> 参数来创建密码授权的客户端。如果你已经运行了 <code v-pre>passport:install</code> 命令，则不需要再运行此命令：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan passport<span class="token punctuation">:</span>client <span class="token operator">--</span>password</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="请求令牌-1" tabindex="-1"><a class="header-anchor" href="#请求令牌-1"><span>请求令牌</span></a></h3>
<p>创建密码授权的客户端后，就可以通过向用户的电子邮件地址和密码向 <code v-pre>/oauth/token</code> 路由发出 <code v-pre>POST</code> 请求来获取访问令牌。而该路由已经由 <code v-pre>Passport::routes</code> 方法注册，因此不需要手动定义它。如果请求成功，会在服务端返回的 JSON 响应中收到一个 <code v-pre>access_token</code> 和 <code v-pre>refresh_token</code>：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$http</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name class-name-fully-qualified">GuzzleHttp<span class="token punctuation">\</span>Client</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$http</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/token'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'form_params'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'grant_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'password'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-secret'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'taylor@laravel.com'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'my-password'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">return</span> <span class="token function">json_decode</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword type-casting">string</span><span class="token punctuation">)</span> <span class="token variable">$response</span><span class="token operator">-></span><span class="token function">getBody</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>{tip} 默认情况下，访问令牌是永久有效的。你可以根据需要 <a href="#configuration">配置访问令牌的有效时间</a>。</p>
</blockquote>
<h3 id="请求所有作用域" tabindex="-1"><a class="header-anchor" href="#请求所有作用域"><span>请求所有作用域</span></a></h3>
<p>使用密码授权机制时，可以通过请求 scope 参数 <code v-pre>*</code> 来授权应用程序支持的所有范围的令牌。如果你的请求中包含 scope 为 <code v-pre>*</code> 的参数，令牌实例上的 <code v-pre>can</code> 方法会始终返回 <code v-pre>true</code>。这种作用域的授权只能分配给使用 <code v-pre>password</code> 授权时发出的令牌：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$http</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/token'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'form_params'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'grant_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'password'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-secret'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'taylor@laravel.com'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'my-password'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'*'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="隐式授权令牌" tabindex="-1"><a class="header-anchor" href="#隐式授权令牌"><span>隐式授权令牌</span></a></h2>
<p>隐式授权类似于授权码授权，但是它只将令牌返回给客户端而不交换授权码。这种授权最常用于无法安全存储客户端凭据的 JavaScript 或移动应用程序。通过调用 <code v-pre>AuthServiceProvider</code> 中的 <code v-pre>enableImplicitGrant</code> 方法来启用这种授权：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 注册任何身份验证/授权服务。</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@return</span> <span class="token class-name"><span class="token keyword">void</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">registerPolicies</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">routes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">enableImplicitGrant</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>调用上面方法开启授权后，开发者可以使用他们的客户端 ID 从应用程序请求访问令牌。接入的应用程序应该向你的应用程序的 <code v-pre>/oauth/authorize</code> 路由发出重定向请求，如下所示：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/redirect'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$query</span> <span class="token operator">=</span> <span class="token function">http_build_query</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'redirect_uri'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'http://example.com/callback'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'response_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'token'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">return</span> <span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/authorize?'</span><span class="token operator">.</span><span class="token variable">$query</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>{tip} <code v-pre>/oauth/authorize</code> 路由在 <code v-pre>Passport::routes</code> 定义中，所以无需再次手动定义此路由。</p>
</blockquote>
<h2 id="客户端凭据授权令牌" tabindex="-1"><a class="header-anchor" href="#客户端凭据授权令牌"><span>客户端凭据授权令牌</span></a></h2>
<p>客户端凭据授权适用于机器到机器的认证。例如，你可以在通过 API 执行维护任务中使用此授权。要使用这种授权，你首先需要在 <code v-pre>app/Http/Kernel.php</code> 的 <code v-pre>$routeMiddleware</code> 变量中添加新的中间件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Passport<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>CheckClientCredentials</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">protected</span> <span class="token variable">$routeMiddleware</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'client'</span> <span class="token operator">=></span> <span class="token class-name static-context">CheckClientCredentials</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>然后在路由上追加这个中间件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/user'</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token operator">...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">middleware</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'client'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>接下来通过向 <code v-pre>oauth/token</code> 接口发出请求来获取令牌:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$guzzle</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name class-name-fully-qualified">GuzzleHttp<span class="token punctuation">\</span>Client</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$guzzle</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/token'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'form_params'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'grant_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client_credentials'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_secret'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-secret'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'your-scope'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">echo</span> <span class="token function">json_decode</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword type-casting">string</span><span class="token punctuation">)</span> <span class="token variable">$response</span><span class="token operator">-></span><span class="token function">getBody</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="个人访问令牌" tabindex="-1"><a class="header-anchor" href="#个人访问令牌"><span>个人访问令牌</span></a></h2>
<p>如果用户要在不经过典型的授权码重定向流的情况下向自己发出访问令牌，可以允许用户通过应用程序的用户界面对自己发出令牌，用户可以因此顺便测试你的 API，或者也可以将其作为一种更简单的发布访问令牌的方式。</p>
<blockquote>
<p>{note} 个人访问令牌是永久有效的，就算使用了 <code v-pre>tokensExpireIn</code> 和 <code v-pre>refreshTokensExpireIn</code> 方法也不会修改它的生命周期。</p>
</blockquote>
<h3 id="创建个人访问客户端" tabindex="-1"><a class="header-anchor" href="#创建个人访问客户端"><span>创建个人访问客户端</span></a></h3>
<p>在你的应用程序发布个人访问令牌之前，你需要在 <code v-pre>passport:client</code> 命令后带上 <code v-pre>--personal</code> 参数来创建对应的客户端。如果你已经运行了 <code v-pre>passport:install</code> 命令，则无需再运行此命令：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">php artisan passport<span class="token punctuation">:</span>client <span class="token operator">--</span>personal</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="管理个人访问令牌" tabindex="-1"><a class="header-anchor" href="#管理个人访问令牌"><span>管理个人访问令牌</span></a></h3>
<p>创建个人访问客户端后，你可以使用 <code v-pre>User</code> 模型实例上的 <code v-pre>createToken</code> 方法来为给定用户发布令牌。<code v-pre>createToken</code> 方法接受令牌的名称作为其第一个参数和可选的 <a href="#token-scopes">作用域</a> 数组作为其第二个参数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$user</span> <span class="token operator">=</span> <span class="token class-name class-name-fully-qualified static-context">App<span class="token punctuation">\</span>User</span><span class="token operator">::</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// Creating a token without scopes...</span></span>
<span class="line"><span class="token variable">$token</span> <span class="token operator">=</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">createToken</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'Token Name'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">accessToken</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// Creating a token with scopes...</span></span>
<span class="line"><span class="token variable">$token</span> <span class="token operator">=</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">createToken</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'My Token'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'place-orders'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">accessToken</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="json-api-1" tabindex="-1"><a class="header-anchor" href="#json-api-1"><span>JSON API</span></a></h4>
<p>Passport 中也有用来管理个人访问令牌的 JSON API，你可以将其与自己的前端配对，为用户提供管理个人访问令牌的仪表板。下面我们会介绍用于管理个人访问令牌的所有 API 接口。方便起见，我们使用 <a href="https://github.com/mzabriskie/axios" target="_blank" rel="noopener noreferrer">Axios</a> 来演示对 API 的接口发出 HTTP 请求。</p>
<blockquote>
<p>{tip} 如果你不想实现自己的个人访问令牌管理的前端界面，可以根据 <a href="#frontend-quickstart">前端快速上手</a> 在几分钟内组建功能齐全的前端界面。</p>
</blockquote>
<h4 id="get-oauth-scopes" tabindex="-1"><a class="header-anchor" href="#get-oauth-scopes"><span><code v-pre>GET /oauth/scopes</code></span></a></h4>
<p>此路由会返回应用程序中定义的所有 <a href="#scopes">作用域</a>。你可以使用此路由列出用户可能分配给个人访问令牌的范围：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">axios<span class="token operator">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/scopes'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        console<span class="token operator">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token operator">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="get-oauth-personal-access-tokens" tabindex="-1"><a class="header-anchor" href="#get-oauth-personal-access-tokens"><span><code v-pre>GET /oauth/personal-access-tokens</code></span></a></h4>
<p>此路由返回认证用户创建的所有个人访问令牌。这主要用于列出所有用户的令牌，以便他们可以编辑或删除它们：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">axios<span class="token operator">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/personal-access-tokens'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        console<span class="token operator">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token operator">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="post-oauth-personal-access-tokens" tabindex="-1"><a class="header-anchor" href="#post-oauth-personal-access-tokens"><span><code v-pre>POST /oauth/personal-access-tokens</code></span></a></h4>
<p>此路由创建新的个人访问令牌。它需要两个数据：令牌的名称和应该分配给令牌的作用范围：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token punctuation">{</span></span>
<span class="line">    name<span class="token punctuation">:</span> <span class="token string single-quoted-string">'Token Name'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token argument-name">scopes</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">axios<span class="token operator">.</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/personal-access-tokens'</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        console<span class="token operator">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token operator">.</span>data<span class="token operator">.</span>accessToken<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">response</span> <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// List errors on response...</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="delete-oauth-personal-access-tokens-token-id" tabindex="-1"><a class="header-anchor" href="#delete-oauth-personal-access-tokens-token-id"><span><code v-pre>DELETE /oauth/personal-access-tokens/{token-id}</code></span></a></h4>
<p>此路由可用于删除个人访问令牌：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">axios<span class="token operator">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/oauth/personal-access-tokens/'</span> <span class="token operator">+</span> tokenId<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="路由保护" tabindex="-1"><a class="header-anchor" href="#路由保护"><span>路由保护</span></a></h2>
<h3 id="通过中间件" tabindex="-1"><a class="header-anchor" href="#通过中间件"><span>通过中间件</span></a></h3>
<p>Passport 包含一个 <a href="https://learnku.com/docs/laravel/5.5/authentication#adding-custom-guards" target="_blank" rel="noopener noreferrer">验证保护机制</a> 可以验证请求中传入的访问令牌。配置 <code v-pre>api</code> 的看守器使用 <code v-pre>passport</code> 驱动程序后，只需要在需要有效访问令牌的任何路由上指定 <code v-pre>auth:api</code> 中间件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/user'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">//</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">middleware</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'auth:api'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="传递访问令牌" tabindex="-1"><a class="header-anchor" href="#传递访问令牌"><span>传递访问令牌</span></a></h3>
<p>当调用 Passport 保护下的路由时，接入的 API 应用需要将访问令牌作为 <code v-pre>Bearer</code> 令牌放在请求头 <code v-pre>Authorization</code> 中。例如，使用 Guzzle HTTP 库时：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$client</span><span class="token operator">-></span><span class="token function">request</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'GET'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'/api/user'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'headers'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'Accept'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'application/json'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'Authorization'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Bearer '</span><span class="token operator">.</span><span class="token variable">$accessToken</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="令牌作用域" tabindex="-1"><a class="header-anchor" href="#令牌作用域"><span>令牌作用域</span></a></h2>
<h3 id="定义作用域" tabindex="-1"><a class="header-anchor" href="#定义作用域"><span>定义作用域</span></a></h3>
<p>作用域可以让 API 客户端在请求账户授权时请求特定的权限。例如，如果你正在构建电子商务应用程序，并不是所有接入的 API 应用都需要下订单的功能。你可以让接入的 API 应用只被允许授权访问订单发货状态。换句话说，作用域允许应用程序的用户限制第三方应用程序执行的操作。</p>
<p>你可以在 <code v-pre>AuthServiceProvider</code> 的 <code v-pre>boot</code> 方法中使用 <code v-pre>Passport::tokensCan</code> 方法来定义 API 的作用域。<code v-pre>tokensCan</code> 方法接受一个作用域名称、描述的数组作为参数。作用域描述将会在授权确认页中直接展示给用户，你可以将其定义为任何你需要的内容：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Laravel<span class="token punctuation">\</span>Passport<span class="token punctuation">\</span>Passport</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">tokensCan</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'place-orders'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Place orders'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'check-status'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'Check order status'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="给令牌分配作用域" tabindex="-1"><a class="header-anchor" href="#给令牌分配作用域"><span>给令牌分配作用域</span></a></h3>
<h4 id="请求授权码时" tabindex="-1"><a class="header-anchor" href="#请求授权码时"><span>请求授权码时</span></a></h4>
<p>使用授权码授权请求访问令牌时，接入的应用应该将其所需的作用域指定为 <code v-pre>scope</code> 查询字符串参数。<code v-pre>scope</code> 包含多个作用域名称时，名称之间使用空格分隔：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/redirect'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$query</span> <span class="token operator">=</span> <span class="token function">http_build_query</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'client_id'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'client-id'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'redirect_uri'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'http://example.com/callback'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'response_type'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'code'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">'place-orders check-status'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">return</span> <span class="token function">redirect</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'http://your-app.com/oauth/authorize?'</span><span class="token operator">.</span><span class="token variable">$query</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="个人访问令牌-1" tabindex="-1"><a class="header-anchor" href="#个人访问令牌-1"><span>个人访问令牌</span></a></h4>
<p>使用 <code v-pre>User</code> 模型的 <code v-pre>createToken</code> 方法发放个人访问令牌时，可以将所需作用域的数组作为第二个参数传给此方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$token</span> <span class="token operator">=</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token function">createToken</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'My Token'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'place-orders'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">accessToken</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="检查作用域" tabindex="-1"><a class="header-anchor" href="#检查作用域"><span>检查作用域</span></a></h3>
<p>Passport 包含两个中间件，可用于验证传入的请求是否已被授予给定作用域的令牌进行身份验证。使用之前，需要将下面的中间件添加到 <code v-pre>app/Http/Kernel.php</code> 文件的 <code v-pre>$routeMiddleware</code> 属性中：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'scopes'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>Laravel<span class="token punctuation">\</span>Passport<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>CheckScopes</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token string single-quoted-string">'scope'</span> <span class="token operator">=></span> <span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>Laravel<span class="token punctuation">\</span>Passport<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>CheckForAnyScope</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="检查所有作用域" tabindex="-1"><a class="header-anchor" href="#检查所有作用域"><span>检查所有作用域</span></a></h4>
<p>路由可以使用 <code v-pre>scopes</code> 中间件来检查当前请求是否拥有指定的 <em>所有</em> 作用域：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/orders'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 访问令牌具有 "check-status" and "place-orders" 的作用域...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">middleware</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'scopes:check-status,place-orders'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="检查任意作用域" tabindex="-1"><a class="header-anchor" href="#检查任意作用域"><span>检查任意作用域</span></a></h4>
<p>路由可以使用 <code v-pre>scope</code> 中间件来检查当前请求是否拥有指定的 <em>任意</em> 作用域：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/orders'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// Access token has either "check-status" or "place-orders" scope...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">middleware</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'scope:check-status,place-orders'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="检查令牌实例上的作用域" tabindex="-1"><a class="header-anchor" href="#检查令牌实例上的作用域"><span>检查令牌实例上的作用域</span></a></h4>
<p>就算访问令牌验证的请求已经通过应用程序的验证，你仍然可以使用当前授权 <code v-pre>User</code> 实例上的 <code v-pre>tokenCan</code> 方法来验证令牌是否拥有指定的作用域：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Route</span><span class="token operator">::</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/orders'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">tokenCan</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'place-orders'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">//</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="使用-javascript-接入-api" tabindex="-1"><a class="header-anchor" href="#使用-javascript-接入-api"><span>使用 JavaScript 接入 API</span></a></h2>
<p>在构建 API 时，如果能通过 JavaScript 应用接入自己的 API 将会给开发过程带来极大的便利。这种 API 开发方法允许你使用自己的应用程序的 API 和别人共享的 API。你的 Web 应用程序、移动应用程序、第三方应用程序以及可能在各种软件包管理器上发布的任何 SDK 都可能会使用相同的API。</p>
<p>通常，如果要从 JavaScript 应用程序中使用 API，则需要手动向应用程序发送访问令牌，并将其传递给应用程序。但是，Passport 有一个可以处理这个问题的中间件。将 <code v-pre>CreateFreshApiToken</code> 中间件添加到 <code v-pre>web</code> 中间件组就可以了：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'web'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token comment">// Other middleware...</span></span>
<span class="line">    <span class="token class-name class-name-fully-qualified static-context"><span class="token punctuation">\</span>Laravel<span class="token punctuation">\</span>Passport<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Middleware<span class="token punctuation">\</span>CreateFreshApiToken</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Passport 的这个中间件将会在你所有的对外请求中添加一个 <code v-pre>laravel_token</code> cookie。该 cookie 将包含一个加密后的 <a href="https://jwt.io/" target="_blank" rel="noopener noreferrer">JWT</a> ，Passport 将用来验证来自 JavaScript 应用程序的 API 请求。至此，你可以在不明确传递访问令牌的情况下向应用程序的 API 发出请求</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">axios<span class="token operator">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/user'</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token operator">.</span><span class="token function">then</span><span class="token punctuation">(</span>response <span class="token operator">=></span> <span class="token punctuation">{</span></span>
<span class="line">        console<span class="token operator">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token operator">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当使用上面的授权方法时，Axios 会自动带上 <code v-pre>X-CSRF-TOKEN</code> 请求头传递。另外，默认的 Laravel JavaScript 脚手架会让 Axios 发送 <code v-pre>X-Requested-With</code> 请求头:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line">window<span class="token operator">.</span>axios<span class="token operator">.</span>defaults<span class="token operator">.</span>headers<span class="token operator">.</span>common <span class="token operator">=</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token string single-quoted-string">'X-Requested-With'</span><span class="token punctuation">:</span> <span class="token string single-quoted-string">'XMLHttpRequest'</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>{note} 如果你用了其他的 JavaScript 框架，应确保配置了每次对外请求都会带有 <code v-pre>X-CSRF-TOKEN</code> 和 <code v-pre>X-Requested-With</code> 请求头。</p>
</blockquote>
<h2 id="事件" tabindex="-1"><a class="header-anchor" href="#事件"><span>事件</span></a></h2>
<p>Passport 在发出访问令牌和刷新令牌时触发事件。 在应用程序的 <code v-pre>EventServiceProvider</code> 中为这些事件追加监听器，可以通过触发这些事件来修改或删除数据库中的其他访问令牌：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * The event listener mappings for the application.</span>
<span class="line"> *</span>
<span class="line"> * <span class="token keyword">@var</span> <span class="token class-name"><span class="token keyword">array</span></span></span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">protected</span> <span class="token variable">$listen</span> <span class="token operator">=</span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'Laravel\Passport\Events\AccessTokenCreated'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'App\Listeners\RevokeOldTokens'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token string single-quoted-string">'Laravel\Passport\Events\RefreshTokenCreated'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'App\Listeners\PruneOldTokens'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="测试" tabindex="-1"><a class="header-anchor" href="#测试"><span>测试</span></a></h2>
<p>Passport 的 <code v-pre>actingAs</code> 方法可以用于指定当前已认证的用户及其作用域。 <code v-pre>actingAs</code> 方法第一个参数是用户实例，第二个参数是应该授予用户令牌的作用范围的数组:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testServerCreation</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Passport</span><span class="token operator">::</span><span class="token function">actingAs</span><span class="token punctuation">(</span></span>
<span class="line">        <span class="token function">factory</span><span class="token punctuation">(</span><span class="token class-name static-context">User</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">[</span><span class="token string single-quoted-string">'create-servers'</span><span class="token punctuation">]</span></span>
<span class="line">    <span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$response</span> <span class="token operator">=</span> <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'/api/create-server'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token variable">$response</span><span class="token operator">-></span><span class="token function">assertStatus</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="译者署名" tabindex="-1"><a class="header-anchor" href="#译者署名"><span>译者署名</span></a></h2>
<table>
<thead>
<tr>
<th>用户名</th>
<th>头像</th>
<th>职能</th>
<th>签名</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://github.com/kirisky" target="_blank" rel="noopener noreferrer">@Kirisky</a></td>
<td><img src="https://cdn.learnku.com/uploads/avatars/18491_1503379318.jpeg?imageView2/1/w/100/h/100" alt="100"></td>
<td>翻译</td>
<td>部分关键字翻译参考 <a href="https://github.com/KevinDiamen" target="_blank" rel="noopener noreferrer">@KevinDiamen</a></td>
</tr>
<tr>
<td>Cloes</td>
<td><img src="https://cdn.learnku.com/uploads/avatars/6187_1477389867.jpg?imageView2/1/w/100/h/100" alt="100"></td>
<td>翻译</td>
<td>我的<a href="https://github.com/cloes" target="_blank" rel="noopener noreferrer">github</a></td>
</tr>
<tr>
<td><a href="https://learnku.com/users/5350" target="_blank" rel="noopener noreferrer">@JokerLinly</a></td>
<td><img src="https://cdn.learnku.com/uploads/avatars/5350_1481857380.jpg" alt="5350_1481857380.jpg"></td>
<td>Review</td>
<td>Stay Hungry. Stay Foolish.</td>
</tr>
</tbody>
</table>
<hr>
<blockquote>
<p>{note} 欢迎任何形式的转载，但请务必注明出处，尊重他人劳动共创开源社区。</p>
<p>转载请注明：本文档由 Laravel China 社区 <a href="https://laravel-china.org/" target="_blank" rel="noopener noreferrer">laravel-china.org</a> 组织翻译，详见 <a href="https://learnku.com/laravel/t/5756/laravel-55-document-translation-call-come-and-join-the-translation" target="_blank" rel="noopener noreferrer">翻译召集帖</a>。</p>
<p>文档永久地址： <a href="https://learnku.com/docs/laravel" target="_blank" rel="noopener noreferrer">《Laravel 中文文档》</a></p>
</blockquote>
</div></template>


